/*
*  Copyright 2019-2023 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package me.zhengjie.modules.system.service.impl;

import cn.hutool.core.io.IoUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import me.zhengjie.config.BaseConstants;
import me.zhengjie.config.StatusEnum;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.system.domain.Plugin;
import me.zhengjie.modules.system.domain.PluginDetail;
import me.zhengjie.modules.system.domain.vo.PluginCreateVo;
import me.zhengjie.modules.system.domain.vo.PluginQueryCriteria;
import me.zhengjie.modules.system.mapper.PluginDetailMapper;
import me.zhengjie.modules.system.mapper.PluginMapper;
import me.zhengjie.modules.system.service.PluginService;
import me.zhengjie.utils.FileUtil;
import me.zhengjie.utils.PageResult;
import me.zhengjie.utils.PageUtil;
import me.zhengjie.utils.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* @description 服务实现
* @author lxp
* @date 2024-11-11
**/
@Service
public class PluginServiceImpl extends ServiceImpl<PluginMapper, Plugin> implements PluginService {
    @Autowired
    private PluginMapper pluginMapper;
    @Autowired
    private PluginDetailMapper pluginDetailMapper;



    @Override
    public PageResult<Plugin> queryAll(PluginQueryCriteria criteria, Page<Object> page){
        List<String> elPermissions = SecurityUtils.getCurrentUser().getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());
        if(!elPermissions.contains("admin")) {
            criteria.setUserId(SecurityUtils.getCurrentUserId());
        }
        return PageUtil.toPage(pluginMapper.findAll(criteria, page));
    }

    @Override
    public List<Plugin> queryAll(PluginQueryCriteria criteria){
        List<String> elPermissions = SecurityUtils.getCurrentUser().getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());
        if(!elPermissions.contains("admin")) {
            criteria.setUserId(SecurityUtils.getCurrentUserId());
        }
        return pluginMapper.findAll(criteria);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(PluginCreateVo resources) {
        if(resources.getId() != null) {
            throw new BadRequestException("不能新增已存在的插件");
        }
        Plugin plugin = new Plugin();
        BeanUtils.copyProperties(resources,plugin);
        plugin.setCreateTime(Timestamp.valueOf(LocalDateTime.now()));
        plugin.setCreateBy(SecurityUtils.getCurrentUserId().toString());
        plugin.setStatus(BaseConstants.ENABLE_STRING);
        plugin.setVersionLasted(0);
        this.save(plugin);
        if(resources.getFile() != null) {
            String content = null;
            try {
                content = IoUtil.readUtf8(resources.getFile().getInputStream());
            } catch (IOException e) {
                log.error("文件解析出错",e);
                throw new BadRequestException("文件内容解析出错");
            }

            PluginDetail pluginDetail = new PluginDetail();
            pluginDetail.setPluginId(plugin.getId());
            pluginDetail.setVersion(1);
            pluginDetail.setPluginDesc(resources.getPluginDetailDesc());
            pluginDetail.setStatus(BaseConstants.DISABLE_STRING);
            pluginDetail.setPluginsContent(content);
            pluginDetail.setCreateTime(Timestamp.valueOf(LocalDateTime.now()));
            pluginDetail.setCreateBy(SecurityUtils.getCurrentUserId().toString());
            pluginDetailMapper.insert(pluginDetail);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(PluginCreateVo resources) {
        if(resources.getId() == null) {
            throw new BadRequestException("插件id不能为空");
        }
        Plugin plugin = getById(resources.getId());
        if(plugin == null) {
            throw new BadRequestException("插件不存在");
        }
        List<String> elPermissions = SecurityUtils.getCurrentUser().getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());
        if(!elPermissions.contains("admin") && !plugin.getCreateBy().equals(String.valueOf(SecurityUtils.getCurrentUserId()))) {
            throw new BadRequestException("只有创建者才能修改");
        }
        BeanUtils.copyProperties(resources,plugin);
        plugin.setUpdateTime(Timestamp.valueOf(LocalDateTime.now()));
        plugin.setUpdateBy(SecurityUtils.getCurrentUserId().toString());

        if(resources.getFile() != null) {
            //先删除待审核的版本,然后新增版本
            UpdateWrapper<PluginDetail> updateWrapper = new UpdateWrapper<>();
            PluginDetail toUpdate = new PluginDetail();
            toUpdate.setStatus(StatusEnum.REJECT.getCode());
            toUpdate.setApproveDesc("重新上传后自动拒绝待审批插件版本");
            updateWrapper.eq("plugin_id",plugin.getId());
            updateWrapper.eq("status",StatusEnum.INIT.getCode());
            pluginDetailMapper.update(toUpdate,updateWrapper);

            plugin.setStatus(BaseConstants.DISABLE_STRING);
            String content = null;
            try {
                content = IoUtil.readUtf8(resources.getFile().getInputStream());
            } catch (IOException e) {
                log.error("文件解析出错",e);
                throw new BadRequestException("文件内容解析出错");
            }

            //先查询已有的插件版本
            LambdaQueryWrapper<PluginDetail> wrapper = new LambdaQueryWrapper();
            wrapper.eq(PluginDetail::getPluginId,plugin.getId());
            wrapper.orderByDesc(PluginDetail::getVersion).last(" LIMIT 1 ");
            PluginDetail max = pluginDetailMapper.selectOne(wrapper);
            int version = 1;
            if(max != null) {
                version = max.getVersion() + 1;
            }
            PluginDetail pluginDetail = new PluginDetail();
            pluginDetail.setPluginId(plugin.getId());
            pluginDetail.setVersion(version);
            pluginDetail.setPluginDesc(resources.getPluginDetailDesc());
            pluginDetail.setStatus(BaseConstants.DISABLE_STRING);
            pluginDetail.setPluginsContent(content);
            pluginDetail.setCreateTime(Timestamp.valueOf(LocalDateTime.now()));
            pluginDetail.setCreateBy(SecurityUtils.getCurrentUserId().toString());
            pluginDetailMapper.insert(pluginDetail);
        }
        saveOrUpdate(plugin);

    }

    public Plugin getPluginById(Long id) {
        Plugin plugin = this.getById(id);
        if(plugin == null) {
            throw new BadRequestException("插件不存在");
        }
        List<String> elPermissions = SecurityUtils.getCurrentUser().getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());
        if(!elPermissions.contains("admin") && !plugin.getCreateBy().equals(String.valueOf(SecurityUtils.getCurrentUserId()))) {
            throw new BadRequestException("只有创建者才能查看");
        }
        return plugin;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(List<Long> ids) {
        removeBatchByIds(ids);
    }

    @Override
    public void download(List<Plugin> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (Plugin plugin : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("名称", plugin.getTitle());
            map.put("昵称", plugin.getNickName());
            map.put("最新版本", plugin.getVersionLasted());
            map.put("插件描述", plugin.getPluginDesc());
            map.put("状态：1启用、0禁用", plugin.getStatus());
            map.put("logo", plugin.getLogo());
            map.put("类型", plugin.getType());
            map.put("创建者", plugin.getCreateBy());
            map.put("更新者", plugin.getUpdateBy());
            map.put("创建日期", plugin.getCreateTime());
            map.put("更新时间", plugin.getUpdateTime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}